package com.i2silly.wxbot.server;

import com.alibaba.fastjson.JSON;
import com.i2silly.wxbot.config.RobotConfiguration;
import com.i2silly.wxbot.config.TempCache;
import com.i2silly.wxbot.constant.WxRobotConstant;
import com.i2silly.wxbot.entity.BotChatroom;
import com.i2silly.wxbot.entity.BotContact;
import com.i2silly.wxbot.entity.BotMonitor;
import com.i2silly.wxbot.entity.BotRobot;
import com.i2silly.wxbot.pojo.BaseSend;
import com.i2silly.wxbot.pojo.TencentChatReceive;
import com.i2silly.wxbot.pojo.WsReceive;
import com.i2silly.wxbot.service.IBotChatroomService;
import com.i2silly.wxbot.service.IBotMonitorService;
import com.i2silly.wxbot.thread.HandleMessageTask;
import com.i2silly.wxbot.utils.PubUtils;
import com.i2silly.wxbot.utils.ReplyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Future;

/**
 * @program: wx-bot
 * @description：机器人服务
 * @author: i2silly
 * @date: 2020年11月21日 15:06:03
 */
@Component
public class RobotServer {

    Logger logger = LoggerFactory.getLogger(RobotServer.class);

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    @Autowired
    private RobotConfiguration robotConfig;

    @Autowired
    private HandleMessageTask task;

    @Autowired
    private TempCache cache;

    private RobotWebsocketServer client;

    @Autowired
    private IBotChatroomService botChatroomService;

    @Autowired
    private IBotMonitorService monitorService;

    /**
     * 上次收到回复消息
     */
//    private Map<String, WsReceive> lastReceive = new HashMap<>();

    /**
     * 监听列表
     */
    private Set<String> tempMonitors = new HashSet<>();

    public void handleOnMessage(String s) {
        WsReceive receive = JSON.parseObject(s, WsReceive.class);
        if (null == receive) {
            return;
        }
        if (receive.getType() != 5005) {
            logger.info(receive.toString());
        }
        try {
            switch (receive.getType()) {
                case 1:
                    logger.info("接收到消息啦");
                    execMessage(receive);
                    break;
                case 1000:
                    // 系统提醒
//                    WsReceive{type=10000, content='"大潘"邀请你加入了群聊，群聊参与人还有：朝闻道、Zouzz、对方正在讲话......、哥、未名。、🍃林百万、冰点คิดถึง、永远的MAMBA、算命找我、奔跑的五花肉🐷', id='20201215192220', receiver='5142327073@chatroom', sender='', srvid=1, time='2020-12-15 19:22:20', command=-1}
                    //{"content":"你邀请\"2silly\"加入了群聊  ","id":"20201215192942","receiver":"5142327073@chatroom","sender":"","srvid":1,"time":"2020-12-15 19:29:42","type":10000}
                    // {"content":"\"冰点คิดถึง\" 拍了拍自己","id":"20201215194126","receiver":"5142327073@chatroom","sender":"","srvid":1,"time":"2020-12-15 19:41:26","type":10000}
                    break;
                case 6500:
                    // 保存机器人
                    saveRobot(receive.getContent());
                    break;
                case 5000:
                    // 保存联系人 2.9修改
                    saveRobotContact(receive.getContent());
                    break;
                case 5010:
                    // 获取群列表 废弃
                    // saveRobotChatroom(receive.getContent());
                    break;
                case 5020:
                    // 保存群成员
                    saveChatroomMember(receive.getContent());
                    break;
                default:
                    logger.info(s);
                    // 初次获取个人信息及联系人信息
                    if (PubUtils.isEmpty(robotConfig.getBotWechatId())) {
                        // 个人信息
                        sendGetRobot();
                    }

            }
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
    }

    // 发送消息============================================
    /**
     * 获取机器人信息
     */
    public void sendGetRobot() {
        // 个人信息
        BaseSend data = new BaseSend();
        data.setId(PubUtils.getTime(System.currentTimeMillis(), dtf));
        data.setType(WxRobotConstant.GET_SELF_INFO_TYPE);
        data.setWxid("ROOT");
        data.setContent("op:personal info");
        client.send(JSON.toJSONString(data));
    }

    /**
     * 获取联系人
     */
    public void sendGetContact() {
        BaseSend data = new BaseSend();
        data.setId(PubUtils.getTime(System.currentTimeMillis(), dtf));
        data.setType(WxRobotConstant.GET_CONTACT_LIST_TYPE);
        data.setWxid("null");
        data.setContent("user list");
        client.send(JSON.toJSONString(data));
    }

    /**
     * 获取所有群成员
     * @param chatroomId 群id
     */
    public void sendGetChatroomMember(String chatroomId) {
        BaseSend data = new BaseSend();
        data.setId(PubUtils.getTime(System.currentTimeMillis(), dtf));
        data.setType(WxRobotConstant.GET_CHATROOM_MEMBER_TYPE);
        data.setWxid("null");
        data.setContent(chatroomId);
        client.send(JSON.toJSONString(data));
    }
    // ===================================================

    // 保存信息============================================

    /**
     * 保存机器人
     *
     * @param s 机器人数据
     * @return 是否
     */
    private boolean saveRobot(String s) {
        Future<BotRobot> robotFuture = task.saveRobot(s);
        try {
            // 等待线程执行完毕
            while (!robotFuture.isDone()) {
                Thread.sleep(100);
            }
            BotRobot robot = robotFuture.get();
            if (null != robot) {
                robotConfig.setWxCode(robot.getWxCode());
                robotConfig.setWxid(robot.getWxid());
                robotConfig.setBotWechatId(robot.getId());
                robotConfig.setName(robot.getNick());
                if (!cache.getInit(WxRobotConstant.ROBOT_INIT)) {
                    logger.info("初始化 发送获取联系人");
                    sendGetContact();
                    cache.addCache(WxRobotConstant.ROBOT_INIT, true);
                }
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存联系人
     * @param s 联系人信息
     * @return 是否
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRobotContact(String s) {
        try {
            Future<Boolean> future = task.saveContactList(s);
            while (!future.isDone()) {
                logger.info("等待获取联系人线程执行结束");
                Thread.sleep(100);
            }

            // 获取联系人缓存
//            Map<String, BotContact> contacts = cache.getContacts();
//            logger.info("联系人缓存：" + contacts);
            if (future.get()) {
                if (!cache.getInit(WxRobotConstant.CONTACT_INIT)) {
                    // 删除不存在的群
                    delChatroom();
                    // 设置监听列表缓存
                    setMonitor();
                    cache.addCache(WxRobotConstant.CONTACT_INIT, true);
                }
            }
            return future.get();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存群
     *
     * @param s 群成员信息
     * @return 是否
     */
    public boolean saveChatroomMember(String s) {
        if (PubUtils.isEmpty(s)) {
            return false;
        }
        try {
            List<BotChatroom> list = JSON.parseArray(s, BotChatroom.class);
            if (PubUtils.isEmpty(list)){
                return false;
            }
            Future<Boolean> future = task.saveChatroomMember(list);
            return future.get();
        }catch (Exception e) {
            logger.info(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 删除不在联系人中的群
     *
     * @return 是否
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean delChatroom() {
        try{
            Map<String, BotContact> contacts = cache.getContacts();
            if (PubUtils.isEmpty(contacts)) {
                return botChatroomService.delByPid(robotConfig.getBotWechatId());
            }
            List<String> list = new ArrayList<>();
            for (String s : contacts.keySet()) {
                if(s.endsWith("@chatroom")){
                    list.add(s);
                }
            }
            if (PubUtils.isEmpty(list)) {
                return botChatroomService.delByPid(robotConfig.getBotWechatId());
            }
            List<String> chatroomId = botChatroomService.distinctChatroomId(robotConfig.getBotWechatId());
            chatroomId.removeIf(list::contains);
            if (PubUtils.isNotEmpty(chatroomId)) {
                botChatroomService.delByChatroomIds(robotConfig.getBotWechatId(), chatroomId);
            }
            return true;
        }catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 设置监听列表缓存
     */
    public void setMonitor() {
        List<BotMonitor> monitors = monitorService.listByPid(robotConfig.getBotWechatId());
        if (PubUtils.isEmpty(monitors)) {
            return;
        }
        for (BotMonitor monitor : monitors) {
            tempMonitors.add(monitor.getMonitorWxid());
        }
        cache.addCache(WxRobotConstant.MONITOR_WXID_CACHE, tempMonitors);
    }
    // ===================================================

    // 处理默认返回消息======================================

    public void execMessage(WsReceive receive) {
        // 未完成初始化不执行
        if (!cache.getInit(WxRobotConstant.ROBOT_INIT) || !cache.getInit(WxRobotConstant.CONTACT_INIT)) {
            logger.info("未完成初始化....");
            return;
        }
        // 发送人设置
        String sender = receive.getSender();
        String receiver = receive.getReceiver();
        if ("self".equals(sender) || PubUtils.isEmpty(sender) || PubUtils.isEmpty(receiver)){
            // 自己发送
            return;
        }
        // 联系人实时赋值
        if (receiver.endsWith("@chatroom")){
            sender = receiver;
            // 发送获取群信息
           if (!cache.getChatroomIds().contains(sender)){
               logger.info("发送获取群列表信息");
               sendGetChatroomMember(sender);
           }
        }
        if (!tempMonitors.contains(sender)){
            return;
        }
        String lastKey = sender;
        String content = receive.getContent();
        if (sender.endsWith("@chatroom")){
            lastKey += "&" + receive.getSender();
            logger.info("上次发送的key:" + lastKey);
        }
        WsReceive wsReceive = cache.getLastWsReceive(lastKey);
        if (!content.contains(robotConfig.getWake()) && !content.contains(robotConfig.getName()) && null == wsReceive){
            return;
        }
        content = content.replaceAll(robotConfig.getWake(),"");
        content = content.replaceAll("@"+ robotConfig.getName(),"");
        content = content.replaceAll(" ","");
        logger.info("接收内容：" + content);
        String[] arr = {"渣男,渣男语录,情话,甜蜜的话"};
        String sendContent;
        String[] close = {"关闭","退出","再见","拜拜"};
        if (PubUtils.contains(arr,content)){
            sendContent = PubUtils.doGet(WxRobotConstant.SWEET_CHAT,null);
        }else if (PubUtils.contains(close,content)){
            sendContent = "好的，再见";
            receive = null;
            client.sendMessage(sendContent, sender);
        }else{
            Map<String, Object> map = ReplyUtil.smartChat(content);
            String s = PubUtils.doGet(WxRobotConstant.TENCENT_CHAT, map);
            TencentChatReceive chatReceive = JSON.parseObject(s, TencentChatReceive.class);
            if (chatReceive.getRet() != 0) {
                sendContent = PubUtils.doGet(WxRobotConstant.SWEET_CHAT,null);
            }else{
                TencentChatReceive.Data data = chatReceive.getData();
                if (data == null || data.getAnswer() == null){
                    sendContent = PubUtils.doGet(WxRobotConstant.SWEET_CHAT,null);
                }else {
                    sendContent = data.getAnswer();
                }
            }
        }
        logger.info("发送消息："+ sendContent);
        cache.addLastWsReceive(lastKey, receive);
        client.sendMessage(sendContent, sender);
    }

    // ===================================================

    public RobotWebsocketServer getClient() {
        return client;
    }

    public void setClient(RobotWebsocketServer client) {
        this.client = client;
    }

    public TempCache getCache() {
        return cache;
    }

    public void setCache(TempCache cache) {
        this.cache = cache;
    }
}
